<template>
  <view class="su-member-picker">
    <view class="su-member-picker-handler" @click="show=!show">
      <text class="su-member-picker-value" v-if="!multiple && value && value.length">{{value[0][defaultProps.name]}}</text>
      <text class="su-member-picker-value" v-else-if="multiple && value && value.length==1">{{value[0][defaultProps.name]}}</text>
      <text class="su-member-picker-value" v-else-if="multiple && value && value.length>1">{{value[0][defaultProps.name]}}<text
          class="color-gray"> 等{{value.length}}人</text></text>
      <text class="su-member-picker-placeholder" v-else>{{placeholder}}</text>
      <text class="su-member-picker-arrow iconfont icon-down-arrow-line"></text>
    </view>

    <u-popup :show="show" @close="show=false" @open="show=true">
      <view class="su-member-picker__popup-container">
        <view class="p10">
          <u-search v-model="searchKey" placeholder="输入关键词搜索" :showAction="false" @search="onSearch"></u-search>
        </view>
        <view class="su-member-picker-header">
          按组织架构显示 <u-switch v-model="selectFromTree"></u-switch>
        </view>
        <view class="select-options-box" v-show="!selectFromTree">
          <view class="mt30 mb30 align-center" v-if="allMemberListLoading">
            <su-list-loading>加载中...</su-list-loading>
          </view>
          <view class="mt30" v-if="!allMemberList.length && !allMemberListLoading">
            <su-empty></su-empty>
          </view>
          <view class="member-list" v-if="allMemberList.length">
            <template v-for="item in allMemberList">
              <view class="member-list__item" @click="checkOrCancelCheck(item)"
                :class="{ disabled: disabledMembers.indexOf(item[defaultProps.id]) !== -1 }"
                :key="item[defaultProps.id]">
                <view class="member-avatar">
                  <image :src="item[defaultProps.img] ? item[defaultProps.img] : '../../../static/images/avatar.jpg'" />
                </view>
                <view class="member-main">
                  <view class="member-name">{{ item[defaultProps.name] || item[defaultProps.uName] }}</view>
                  <view class="member-props">{{ item[defaultProps.uName] }}</view>
                </view>
                <view class="member-asider">
                  <text class="iconfont icon-radio-checked ckeckbox-icon color-primary"
                    v-if="checkedIndex(item[defaultProps.id])!==-1"></text>
                  <text class="iconfont icon-radio-notcheck ckeckbox-icon" v-else></text>
                </view>
              </view>
            </template>
          </view>
        </view>
        <!-- end 从所有人中选择（含搜索） -->
        <!-- 从组织架构中选择 -->
        <view class="select-options-box" :class="{ mt0: breadNav.length > 1 }" v-show="selectFromTree">
          <view class="bread-nav" v-if="breadNav.length > 1">
            <template v-for="(item,index) in breadNav">
              <text :key="item.deptId">
                <template v-if="index !== (breadNav.length - 1)">
                  <a href="javascript:;" @click="breadNavClickHandler(item, index)">{{ item.deptName }}</a>
                  <text class="bread-nav-spaceline">/</text>
                </template>
                <template v-else>
                  <text class="bread-nav-current">{{ item.deptName }}</text>
                </template>
              </text>
            </template>
          </view>
          <view class="mt30 mb30 align-center" v-if="departmentDetailLoading">
            <su-list-loading size="24px">加载中...</su-list-loading>
          </view>
          <view class="mt30" v-if="!childDepartments.length && !departmentMemebers.length && !departmentDetailLoading">
            <su-empty></su-empty>
          </view>
          <view class="member-list" v-if="childDepartments.length">
            <template v-for="(item,index) in childDepartments">
              <view class="member-list__item" :key="index" @click="showChildDepartmentDetail(item)">
                <view class="member-avatar">
                  <image fit="contain" round
                    :src="item[defaultProps.img] ? item[defaultProps.img] : '../../static/image/avatar.jpg'" />
                </view>
                <view class="member-main">
                  <view class="member-name">{{ item.deptName || '' }}</view>
                  <view class="member-props">主管：{{ item.leader }}</view>
                </view>
                <view class="member-asider">
                  <text class="iconfont icon-arrow-right-line color-gray f12"></text>
                </view>
              </view>
            </template>
          </view>
          <view class="member-list" v-if="departmentMemebers.length">
            <template v-for="item in departmentMemebers">
              <view class="member-list__item" @click="checkOrCancelCheck(item)"
                :class="{ disabled: disabledMembers.indexOf(item[defaultProps.id]) !== -1 }"
                :key="item[defaultProps.id]">
                <view class="member-avatar">
                  <image fit="contain" round
                    :src="item[defaultProps.img] ? item[defaultProps.img] : $config.defaultUserAvatar" />
                </view>
                <view class="member-main">
                  <view class="member-name">{{ item[defaultProps.name] || item[defaultProps.uName] }}</view>
                  <view class="member-props">{{ item[defaultProps.uName] }}</view>
                </view>
                <view class="member-asider">
                  <text class="iconfont icon-radio-checked ckeckbox-icon color-primary"
                    v-if="checkedIndex(item[defaultProps.id])!==-1"></text>
                  <text class="iconfont icon-radio-notcheck ckeckbox-icon" v-else></text>
                </view>
              </view>
            </template>
          </view>
        </view>
        <!-- end 从组织架构中选择 -->
      </view>
      <view class="confirm-bottom" v-if="multiple">
        <view class="confirm-bottom-select-all" @click="checkAllHandler">
          <text class="iconfont icon-radio-checked ckeckbox-icon color-primary" v-if="checkedAll"></text>
          <text class="iconfont icon-radio-notcheck ckeckbox-icon color-gray" v-else></text>
          全选
        </view>
        <view class="confirm-bottom-count" @click="showResultList = true">
          已选择
          <text class="color-primary ml5 mr5 text-bold">{{checkedCount}}</text> 人
        </view>
        <view class="confirm-bottom-confirmbtn">
          <u-button type="primary" block @click="confirmHandler">确定</u-button>
        </view>
      </view>
      <u-popup :show="showResultList" @close="showResultList=false" @open="showResultList=true">

        <view class="result-list-header" v-if="tempCheckedList.length">
          <view>已选人员列表</view>
          <view class="clear-all-members" @click="clearupAll">
            <text class="iconfont icon-qingchu"></text> 清空
          </view>
        </view>
        <view class="su-member-picker__popup-container">
          <view class="mt30" v-if="!tempCheckedList.length">
            <su-empty text="您啥也没有选～"></su-empty>
          </view>
          <view class="member-list" v-if="tempCheckedList.length">
            <template v-for="item in tempCheckedList">
              <view class="member-list__item" :key="item.MemberId"
                :class="{disabled:disabledMembers.indexOf(item.MemberId)!==-1}">
                <view class="member-avatar">
                  <image :src="item[defaultProps.img] ? item[defaultProps.img] : '../../../static/images/avatar.jpg'" />
                </view>
                <view class="member-main">
                  <view class="member-name">{{item[defaultProps.name] || item[defaultProps.uName]}}</view>
                  <view class="member-props">{{item[defaultProps.uName]}}</view>
                </view>
                <view class="member-asider" @click="checkOrCancelCheck(item)">
                  <text class="iconfont icon-close-line delete-checked-icon"></text>
                </view>
              </view>
            </template>
          </view>
        </view>

      </u-popup>
    </u-popup>

  </view>
</template>

<script>
  /**
   * @description 组织架构里的人选择
   * @date 2022-03-15
   * @version v1.0.1
   * @author xx
   */
  import {
    listUser,
    listUserAll
  } from '@/common/api/sys/sysuser.js'
  import {
    sysdeptList
  } from '@/common/api/sys/sysdept.js'
  export default {
    name: "su-member-picker",
    model: {
      prop: 'value',
      event: 'change'
    },
    props: {
      value: {
        type: Array,
        default () {
          return []
        }
      },
      multiple: {
        type: Boolean,
        default: false
      },
      placeholder: {
        type: [String, Number],
        default: '请选择'
      }
    },
    data() {
      return {
        show: false,
        innerVal: this.value,

        searchKey: "",
        checkedAll: false,
        showResultList: false,
        defaultProps: {
          id: "userId",
          name: "nickName",
          img: "avatar",
          uName: "userName"
        },
        breadNav: [{
          deptId: 0,
          deptName: "全部"
        }],
        disabledMembers: [], //需要禁用
        disabledToast: "",
        tempCheckedList: this.value || [], //选中的列表
        selectFromTree: true, //是否从组织架构里搜索
        curDepartMentId: "0", //当前显示的组织架构部门的id
        allMemberList: [],
        allMemberListLoading: false,
        childDepartments: [],
        departmentMemebers: [],
        departmentDetailLoading: false,
        showPopup: false,
        activeMember: {}
      }
    },
    computed: {
      checkedCount() {
        return this.tempCheckedList.length;
      }
    },
    watch: {
      show(val) {
        this.$store.commit('setPopupOpen', val)
      }
    },
    mounted() {
      this.getAllMemberList();
      this.getsysdeptList()
    },
    methods: {
      getsysdeptList() {
        sysdeptList().then(res => {
          this.childDepartments = res.data || [];
        })
      },
      //选择或取消选择操作
      checkOrCancelCheck(member) {
        if (this.disabledMembers.indexOf(member[this.defaultProps.id]) !== -1) {
          if (this.disabledToast) this.$toast(this.disabledToast);
          return;
        }
        let checkedIndex = this.checkedIndex(member[this.defaultProps.id]);
        if (!this.multiple) {
          //单选
          this.tempCheckedList = [member];
          this.confirmHandler();
          return;
        }
        if (checkedIndex !== -1) {
          //取消选中
          this.tempCheckedList.splice(checkedIndex, 1);
        } else {
          //选中
          this.tempCheckedList.push(member);
        }
        this.countCurrentCheckedMembers();
      },

      //查找某人是否被选中，并返回选中列表中的索引数
      checkedIndex(userId) {
        for (var i in this.tempCheckedList) {
          if (this.tempCheckedList[i][this.defaultProps.id] === userId) return i;
        }
        return -1;
      },

      //全选/全不选操作
      checkAllHandler() {
        this.checkedAll = !this.checkedAll
        let list = this.selectFromTree ?
          this.departmentMemebers :
          this.allMemberList;
        for (var i in list) {
          let member = list[i];
          if (this.disabledMembers.indexOf(member[this.defaultProps.id]) === -1) {
            let checkedIndex = this.checkedIndex(member[this.defaultProps.id]);
            //全不选
            if (!this.checkedAll && checkedIndex !== -1) {
              this.tempCheckedList.splice(checkedIndex, 1);
            }
            //全选
            if (this.checkedAll && checkedIndex === -1) {
              this.tempCheckedList.push(member);
            }
          }
        }
      },

      //比对当前页选中数量，如果等于当前页人员数量，则全选选中，否则全选取消选中
      countCurrentCheckedMembers() {
        if (!this.multiple) return;
        let list = this.selectFromTree ?
          this.departmentMemebers :
          this.allMemberList;
        this.checkedAll = list.every(
          item =>
          this.checkedIndex(item.MemberId) !== -1 ||
          this.disabledMembers.indexOf(item.MemberId) !== -1
        );
      },

      //按关键字搜索人员
      onSearch() {
        this.selectFromTree = false;
        this.allMemberList = [];
        this.getAllMemberList();
      },
      //加载组织架构里的所有人员列表（含搜索）
      getAllMemberList() {
        let params = {
          pageNum: 1,
          pageSize: 999999,
          userName: this.searchKey,
          deptId: '',
        }
        this.allMemberListLoading = true;
        listUser(params).then(res => {
          this.allMemberListLoading = false;
          this.allMemberList = res.rows || [];
        })
      },
      //获取组织架构里某部门的列表
      getDepartmentMembers() {
        if (!this.curDepartMentId) {
          this.departmentMemebers = [];
          this.getsysdeptList()
          return
        }
        let params = {
          pageNum: 1,
          pageSize: 999999,
          userName: this.searchKey,
          deptId: this.curDepartMentId,
        };
        this.departmentDetailLoading = true;
        this.departmentMemebers = [];
        listUser(params).then(res => {
          this.departmentDetailLoading = false;
          this.departmentMemebers = res.rows || [];
        })
      },
      //显示子部门部门列表和人员列表
      showChildDepartmentDetail(item) {
        this.curDepartMentId = item.deptId;
        this.childDepartments = item.children || [];
        this.breadNav.push(item);
        this.getDepartmentMembers();
      },
      //面包屑导航点击
      breadNavClickHandler(item, index) {
        this.showChildDepartmentDetail(item);
        this.breadNav.splice(index + 1, this.breadNav.length - index);
      },
      //确认选择结果
      confirmHandler() {
        const resList = this.tempCheckedList
        this.$emit('input', resList)
        this.$emit('change', resList)
        this.show = false
        this.showResultList = false
      },
      //清空所有选择
      clearupAll() {
        let tempArr = [];
        for (var i in this.tempCheckedList) {
          let item = this.tempCheckedList[i];
          if (this.disabledMembers.indexOf(item.MemberId) !== -1) {
            tempArr.push(item);
          }
        }
        if (tempArr.length) {
          this.$toast("有" + tempArr.length + "个人不能清除");
        }
        this.tempCheckedList = tempArr;
        this.countCurrentCheckedMembers();
      },
    }
  }
</script>

<style lang="scss" scoped>
  .su-member-picker {
    width: 100%;

    &__popup {
      &-container {
        height: 70vh;
        overflow: auto;
      }
    }

    &-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 10upx 30upx;
      border-bottom: solid 10px #f7f7f7;
    }

    &-handler {
      display: flex;
      height: 100%;
      justify-content: space-between;
      align-items: center;
    }

    &-placeholder {
      font-size: 30upx;
      color: #bbb;
    }

    &-value {
      font-size: 30upx;
      color: #333;
    }

    &-arrow {
      color: #aaa;
      font-size: 28upx;
    }

    &-options {
      &-item {
        display: flex;
        align-items: center;
        font-size: 30upx;
        padding: 20upx 30upx;
        border-bottom: solid 1upx #f7f7f7;

        .iconfont {
          font-size: 48upx;
          color: #ddd;
        }

        &__start {
          flex: 1;
        }
      }
    }
  }



  .select-options-box {
    margin-top: 20upx;
  }

  .member {
    &-list {
      background-color: #fff;
      margin-bottom: 30upx;

      &__item {
        display: flex;
        padding: 20upx 30upx;
        position: relative;
        border-bottom: solid 1upx #f7f7f7;

        &:active {
          background-color: #fafafa;
        }

        &.disabled {
          opacity: 0.5;

          &:active {
            background-color: #fff;

            .ckeckbox-icon {
              color: #ddd;
            }
          }
        }
      }
    }

    &-avatar {
      margin-right: 30upx;

      img,
      image {
        width: 40px;
        height: 40px;
        border-radius: 40px;
        display: block;
        background-color: #f7f7f7;
      }
    }

    &-main {
      flex: 1;
    }

    &-asider {
      min-height: 100%;
      display: flex;
      align-items: center;

      .ckeckbox-icon {
        font-size: 50upx;
        transition: all 0.3s;
      }

      .delete-checked-icon {
        font-size: 20upx;
        width: 40upx;
        height: 40upx;
        color: #fff;
        background-color: rgba(0, 0, 0, 0.3);
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 40upx;
        padding-top: 2upx;
        box-sizing: border-box;

        &:active {
          background-color: rgba(0, 0, 0, 1);
        }
      }

      .icon-radio-notcheck {
        color: #ccc;
      }

      .icon-radio-checked {
        color: su-member-picker;
      }
    }

    &-name {
      font-size: 30upx;
      color: #333;
      margin-bottom: 4upx;
    }

    &-props {
      font-size: 24upx;
      color: #999;
    }
  }

  .confirm-bottom {
    margin-bottom: constant(safe-area-inset-bottom);
    margin-bottom: env(safe-area-inset-bottom);
    right: 0;
    display: flex;
    justify-content: space-between;
    padding-left: 30upx;
    background-color: #fff;
    z-index: 3;
    box-shadow: 0 -12upx 40upx rgba(0, 0, 0, 0.07);

    &~.lq-body {
      bottom: 100upx;
    }

    &-count {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #999;

      text {
        text-decoration: underline;
        vertical-align: middle;
        margin-top: -2px;
      }
    }

    &-confirmbtn {
      flex: 1;

      .van-button {
        height: 100upx;
        border-radius: 0;
        font-weight: bold;
      }
    }

    &-select-all {
      display: flex;
      flex: 1;
      justify-content: flex-start;
      align-items: center;

      .iconfont {
        font-size: 40upx;
        color: #aaa;
      }
    }
  }

  .bread-nav {
    font-size: 24upx;
    padding: 20upx 30upx;
    line-height: 2;

    a {
      font-size: 24upx;
    }

    &-spaceline {
      color: #ddd;
      margin: 0 12upx;
      font-weight: 300;
    }

    &-current {
      color: #999;
    }
  }

  .result-list-header {
    height: 88upx;
    display: flex;
    padding: 0 30upx;
    justify-content: space-between;
    align-items: center;
    position: relative;
    font-size: 24upx;
    color: #666;

    .clear-all-members {
      color: $u-error;
    }

    i {
      font-size: 28upx;
      margin-right: 4upx;
    }

    border-bottom: solid 1upx #f7f7f7;
  }
</style>
